If you use this class, I would like to hear from you --
see “Contact” below
Of course, the class and the sample project
are both “Made with REALbasic” ;-)
For REALbasic, see http://www.realsoftware.com
0. Abbreviations & TOC
======================
Abbreviations
-------------
const kPRN = pseudo-random number
const kPRNs = pseudo-random numbers
const kPRNG = pseudo-random number generator
TOC
---
1. What it is
2. Why I wrote it
3. How to use it
4. Why “random()” is not random
5. Reference
5.1 Setup/configuration methods
5.2 kPRN generating methods
5.3 Test methods
6. History
7. Warranty
8. Contact
9. Conclusion
1. What it is
=============
A simple kPRNG, written as replacement for RB’s built-in function rnd(), It allows you to specify the random seed and has overloaded methods for some common tasks (e.g. pick a kPRN from a range).
2. Why I wrote it
=================
Argh, well, hm, I know, you know, there are already some other kPRNG implementations for RB. Well, I needed one for a project of me (an interpreter) and could’t find a both nice & poweful kPRNG implementation at the moment, so I wrote my own -- that was faster than searching the whole RB web ring.
So please excuse me if you have already written or seen a better kPRNG for RB ;-)
3. How to use it
================
Open the sample project, drag the class “RAlea” to the desktop; open your project, drag the little cube “RAlea” from the desktop to your project window.
If you don’t know what the “seed” means or “how random” kPRNG generated numbers are, you probably should consult a nice programming book of your choice; this ReadMe file explains only the special properties of RAlea, not the whole theory of kPRNGs ;-).
But maybe the following section helps you to get started.
4. Why “random()” is not random
===============================
Computers are* determinated machines; so whatever they do is determinable. This is of high interest even for philosophers; or, more exactly, philosophers already have discussed the problem of determination for centuries -- they have asked if there is actually anythink like freedom while everything in this world seems to happen according to causality. From this and similar question a lot of exiting discussions about existence of god(s), freedom, good and evil &c &c &c have arised.**
But we have said, computers are determinated machines: so they have no freedom and you can exactly calculate in advance what they will do.*** So they are exactly what they are supposed to be -- or would you prefer your Mac to say to you: “I’m sorry, but I don’t like to do what you want me to do now”, or to return 5 if you asked for the result of 2 * 2?
There is a little problem. Sometimes you actually want your computer to do something you do not know in advance -- for example, to select a “random” number from a given range of numbers, just like to play at dice (BTW, “alea” is the Latin word for “dice”). But your computer can’t play at dice; you computer can only calulate. So what?
You could use a special kind of hardware equipment that would supply your computer with really “random” input; for example by recording the interference of a disintegrating radio-active substance. But that’s expensive. A common work-around is to calculate an arithmetic series. If you have an algorithm that
- takes an arbitrary number as input (the so-called “random seed”) &
- calculates a long series of numbers from this value,
and the calculated series
- looks random, i.e. doesn’t follow any obvious regularity
- doesn’t repeat the same values too often, i.e. doesn’t return to its initial “seed” value too early,
then you call the numbers calulated by that algorithm “pseudo-random numbers” (kPRNs) and the algorithm itself a “pseudo-random number generator” (kPRNG). The less the calculated series tends to repeat itself, i.e. to return to its “seed”, and the less obvious the regularity of the serious is, the better is a kPRNG.
RB’s built-in rnd() function calls such a kPRNG, and RAlea is a kPRNG. I hope RAlea is the better one.
* Or should be; sometimes I’m not sure ;-)
** For example, see Rousseau, “Emile” book IV, “Confession”; Hume, “An enquiery concerning human understanding”; Augustinus, and many others.
*** You may need another computer for this task.
5. Reference
============
5.1 Setup/configuration methods
-------------------------------
• RAlea()
Default constructor, calls guessSeed() -- see below.
• RAlea(newSeed as double)
Constructor, calls setSeed() -- see below.
• setSeed(newSeed as double)
Sets a new seed value. Here and elsewhere we use a double to allow for huge numbers like 2^48 &c; but the “double” type is used like a “long integer” type, i.e. we ignore the fractional part.
You should only supply numbers >= 0; if you supply a negative number, we use the absolute value.
If you specify the same seed value a second time, RAlea will give you the same series of kPRNs. So if you need “really” random numbers, use a random number for seed -- guessSeed() tries to do so.
Note that you may have to supply big values as new seed to get a reliably “random” random() result from the first call on. If you always supply seeds e.g. below 1000000, the first random() value is always around 0.1, and also the next 2 or 3 random() values are rather similar. To get a really “random” value even from the first call to random() on, you have to set seed to to an arbitrary value between 0 and about 10^15, i.e. to numbers between 0 and the dimension of the constants definded in random().
• guessSeed()
Tries to guess a “random” seed value. This is impossible (as you know), but it seems a reasonable surrogate to calculate something from the result of RB’s microseconds() function -- see comments in code for a full description. Don’t forget that guessSeed() is just a utility for lazy programmers -- if you need better seed selection, just do it yourself and call setSeed().
• getSeed() as double
Gives you the initial seed value of the current series.
• reset()
Resets the kPRNG so it uses the initial seed value of the current series again. Everytime you “reset” RAlea, it will give you the same series of pseudo-random numbers again like initially after setting the seed value; a.reset() is the same as a.setSeed(a.getSeed()), but much faster.
5.2 kPRN generating methods
---------------------------
• random() as double
Like RB’s built-in function rnd().
Returns a double from the range [0;1[ or 0 <= x < 1; that is, the result can be 0, but never 1.
Notice: The result can become 0, for example if the last value of myR was = (kP - kC) / kA.
The result is always < 1 because of the (emulated) modulus operator which (per definitionem) always returns a value <= the second argument, and the second argument is the same kP we use for division; if you ever see “1” in the sample project result list, the “real” result is 0.999999... and this gets rounded to “1” by RB’s str() function.
• random(min as double, max as double) as double
Returns a double from the range [min;max[ or min <= x < max; that is, the result can be min, but never max, like in random().
Notice: Here we don’t use doubles like “long ints”; you may call this method for example “random(0.17, 1.25)”, and could get 0.9871323001... If you need a “long int”, just write: floor(random(…, …)).
Notice: I don’t verify your input for min & max; so please assure yourself that min < max!
• random(min as integer, max as integer) as integer
Returns an integer from the range [min;max] or min <= x <= max; that is, the result can be min and can be max -- at least, it should work so ;-).
Notice: This range is limited by the range of RB’s integer type.
Notice: I don’t verify your input for min & max; so please assure yourself that min < max!
• iace as integer
Returns an integer from the range [1;6] or 1 <= x <= 6, like a dice.
BTW: “alea” is the Latin word for “dice”; “iace aleam”: German »Wirf den Würfel!«, English something like “play at dice!”.
Crossing the Rubicon Caesar said “alea iacta est!” or (according to other sources) “aleae iactae sunt!” to express that the had come to the final decision (cf. Suet. vit. Caes. xxxii) which meant the begin of [yet ano]the[r] Roman civil war (cf. Lucan. de bell. civ.).
5.3 Test methods
----------------
• demonstrateZero()
This method just sets the seed to one of the possible values that allow for (random() = 0). Just to be on the save side ;-)
6. History
==========
1.0.0, 2000-12-31
• First public release
1.1.0, 2001-01-01
• New method demonstrateZero()
• Method setSeed() now calls abs() to assure that seed is >= 0.
• Description of possible results from kPRN generating methods should now be clearer; removed a misleading example.
• We use a privat method fmod() for the floating-point reminder calculation; code is now slower, but much easier to read.
• Improved control order in sample project main window
• Made a very strange observation about the floor() function; see comment in method demonstrateZero(); will try to isolate the problem and report it to the DR list / REALbug it, if possible
1.1.1, 2000-01-03
• Included “Made with RB” Logo in the (new) About Box of the sample project -- RS likes this.
1.1.2, 2000-01-03
• Better documentation for setSeed()
• Better implementation of guessSeed()
• New ReadMe section “Why random() is not random”
1.1.3, 2000-01-03
Oops! the third release today, but I forgot something...
• Minor improvements for the sample project (fits on 640x480, &c)
7. Warranty
===========
No warranty. Use this class and the example project on your own risk.
8. Contact
==========
The most recent version is always available via: http://www.roman-eisele.de/rb/
Corrections, suggestions, patches, fixes, praise, constructive criticism and valuable donations are always welcome. Please keep flame and hatred (if you have any) to yourself ;-) If you just don’t like my class (or me), ignore us; if you think my code could be better, tell me why and how to make it better.
Even if you just use the class, I would like to hear from you -- a simple mail with the message “I use RAlea” helps me much!
Send me an owl or contact me via electronic muggel mail:
mailto:rb@roman-eisele.de
9. Conclusion
=============
Excuse my poor English; I hope my REALbasic is better.